package cn.com.sbell.vss.auth.db;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.com.sbell.vss.ICommander;
import cn.com.sbell.vss.ILogCommander;
import cn.com.sbell.vss.Response;
import cn.com.sbell.vss.Util;
import cn.com.sbell.vss.VissSession;
import cn.com.sbell.vss.VssConstants;
import cn.com.sbell.vss.VssException;
import cn.com.sbell.vss.csg.vap.util.CrossDomainCredential;
import cn.com.sbell.vss.csg.vap.util.RouteSessionMapper;
import cn.com.sbell.vss.ems.dao.IUserDao;
import cn.com.sbell.vss.ems.dao.IUserRoleDao;
import cn.com.sbell.vss.ems.entity.User;
import cn.com.sbell.vss.ems.entity.UserRole;
import cn.com.sbell.vss.servlet.DispatchServlet;
import cn.com.sbell.vss.util.RandomGUID;
import cn.com.sbell.vss.util.SessionHolder;
import cn.com.sbell.vss.util.VssValidator;

/**
 * @author Yifu.HUANG
 * 
 */
public class AuthenticatedByDatabase implements ICommander, ILogCommander {
	private static final Log log = LogFactory
			.getLog(AuthenticatedByDatabase.class);

	private IUserDao userDao;

	private IUserRoleDao userRoleDao;

	private SessionHolder sessionHolder;

	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	public void setUserRoleDao(IUserRoleDao userRoleDao) {
		this.userRoleDao = userRoleDao;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see cn.com.sbell.vss.ICommander#execute(javax.servlet.http.HttpServletRequest)
	 */
	public Response execute(HttpServletRequest request) {
		// prepare response (include parameters)
		Response response = Response.createResponse(request);
		// Document doc = DocumentHelper.createDocument();
		// Element root = doc.addElement("parameters");

		// get parameters
		// get parameters
		String username = request.getParameter("__username");
		String password = request.getParameter("__password");
		if (Util.strIsNull(username)) {
			username = request.getParameter("username");
		}
		if (Util.strIsNull(password)) {
			password = request.getParameter("password");
		}
		String host = Util.getTrimParameter(request, "host");
		String _alarmPort = Util.getTrimParameter(request, "alarmPort");
		String _vapPath = Util.getTrimParameter(request, "vapPath");
		if (host.length() == 0) {// get the client host
			host = request.getRemoteAddr();
			if (host == null || host.length() == 0) {
				host = request.getRemoteHost();
			}
		}

		VssValidator.validateMaxLength("field.user.username", username, true,
				32);
		VssValidator.validateMaxLength("field.user.password", password, false,
				32);
		VssValidator.validateNumber("field.alarmPort", _alarmPort, false,
				VssConstants.DATA_INTEGER);
		VssValidator.validateRequired("field.host", host);
		if(log.isDebugEnabled()){
		log.debug("authenticat by database passed parameter check");
		}
		// prepare query parameters
		Map paramMap = new HashMap();

		paramMap.put("username", username);

		List users = userDao.find(paramMap);
		if (users == null || users.size() != 1) {
			throw new VssException(VssConstants.CODE_AUTHENTICATION_FAILED);
		}

		User user = (User) users.get(0);
		if (user.isDisabled()) {
			throw new VssException(VssConstants.CODE_USER_DISABLED);
		}
		if (user.getPassword() != null && !user.getPassword().equals(password)) {
			throw new VssException(VssConstants.CODE_AUTHENTICATION_FAILED);
		}
		if (user.getUserType() == 3// domain user
				&& request.getParameter("__domainId") == null) {
			throw new VssException(
					VssConstants.CODE_CANNOT_USE_THIS_USERNAME_LOGIN);
		}
		if(log.isDebugEnabled()){
		log.debug("authenticat by database passed get User");
		}
		String sessionId = Util.getSessionId(request);
		if (sessionId == null) {
			sessionId = new RandomGUID().toString();
		}

		// set session data
		VissSession session = new VissSession(sessionId);

		// data.setSessionId(sessionId);
		session.setUserId(user.getId());
		session.setUsername(user.getUsername());
		session.setDisplayName(user.getDisplayName());
		session.setLoginTime(System.currentTimeMillis());
		session.setLastAccessTime(session.getLoginTime());
		session.setIp(host);
		session.setAlarmPort((_alarmPort.length()) == 0 ? -1 : Integer
				.parseInt(_alarmPort));
		session.setOrganizationId(user.getOrganizationId());
		session.setVapPath(_vapPath == null ? "" : _vapPath);
		session.setDomainId(user.getDomainId());
//		add to test
		
		
		sessionHolder.putSession(session);
		sessionHolder.cleanTimeoutSession();
		if(log.isDebugEnabled()){
		log.debug("authenticat by database passed session setter");
		}
		// set roleId
		Map param = new HashMap();
		param.put("userId", user.getId());
		List list = userRoleDao.find(param);

		Map areaRoleMap = null;
		String curDid = null;
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			UserRole ur = (UserRole) iter.next();
			if (!ur.getDomainId().equals(curDid)) {
				curDid = ur.getDomainId();
				areaRoleMap = new HashMap();
				session.setAreaRoleMap(curDid, areaRoleMap);
			}
			areaRoleMap.put(ur.getAreaId(), ur.getRoleId());
		}

		request.setAttribute(VssConstants.KEY_USER_SESSION_DATA, session);
		if (log.isDebugEnabled()) {
			log.debug("Session is "
					+ request.getAttribute(VssConstants.KEY_USER_SESSION_DATA));
		}
//		==================================================== added vondart
		CrossDomainCredential cdc= new CrossDomainCredential();
		cdc.setNextDomainPassWord(Util.MD5("12345678"));
		cdc.setNextDomainUserName("root");
		String route=null;
		try {
			route=Util.getRoute(request);
			if((null!=route)&&(null!=cdc.getNextDomainUserName())&&(null!=cdc.getNextDomainPassWord()))
			{
				CrossDomainCredential cdcExisting=	RouteSessionMapper.checkRoute(route, request);
				if(null==cdcExisting){
				RouteSessionMapper.updateRoute(route, cdc,request);
				log.debug("authenticat by database update nextDomainUserName, nextDomainPassWord");
				}
			}
		} catch (VssException e) {
			// TODO: handle exception
			Response res = Response.createResponse(request);
			res.setReturnCode(e.getResultCode());
			String returnMessage = DispatchServlet
			.getMessage("code." + res.getReturnCode(),
					e.getFields(),request);
			res.setReturnMessage(returnMessage);
			return res;
		}
//		===========================================================
		
		Map parameters = new java.util.LinkedHashMap();
		parameters.put("userId", user.getId());
		parameters.put("username", username);
		parameters.put("sessionId", sessionId);
		parameters.put("sessionTimeout", String.valueOf(sessionHolder
				.getSessionTimeout() / 1000L));

		// set parameters xml string, then return
		response.setParameters(parameters);
		return response;

	}

	public void setSessionHolder(SessionHolder sessionHolder) {
		this.sessionHolder = sessionHolder;
	}

	public void setLocalIp(String localIp) {
		// do nothing
	}

	public void setNasType(int nasType) {
		// do nothing
	}
}
